package cn.assassinx.assassin.sample.feign;

import cn.assassinx.assassin.client.annotation.EnableAssassinResourceServer;
import cn.assassinx.assassin.client.util.AssassinResult;
import feign.Logger;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.AllArgsConstructor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Barton
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableAssassinResourceServer
public class AssassinMutliTenantFeignSampleApplication {

	@Configuration
	public class FeignConfig implements RequestInterceptor {
		@Override
		public void apply(RequestTemplate requestTemplate) {
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
			HttpServletRequest request = attributes.getRequest();
			//添加token
			requestTemplate.header("Authorization", request.getHeader("Authorization"));
			requestTemplate.header("TenantId", request.getHeader("TenantId"));
		}
	}

	@Bean
	Logger.Level feginLoggerLevel() {
		return Logger.Level.FULL;
	}

	public static void main(String[] args) {
		SpringApplication.run(AssassinMutliTenantFeignSampleApplication.class, args);
	}

	@FeignClient(name = "assassin-mutli-tenant-sample", fallback = TestServiceFallback.class, configuration = FeignConfiguration.class)
	public interface TestService {
		@GetMapping("/test/1")
		AssassinResult test1();

		@GetMapping("/test/2")
		AssassinResult test2();
	}

	class FeignConfiguration {
		@Bean
		public TestServiceFallback testServiceFallback() {
			return new TestServiceFallback();
		}
	}

	class TestServiceFallback implements TestService {
		@Override
		public AssassinResult test1() {
			return new AssassinResult("test1 fallback");
		}

		@Override
		public AssassinResult test2() {
			return new AssassinResult("test2 fallback");
		}
	}

	@RestController
	@AllArgsConstructor
	public class TestController {

		private final TestService testService;

		@GetMapping("/test/feign/1")
		public AssassinResult testFeign1() {
			return new AssassinResult(testService.test1().getData());
		}

		@GetMapping("/test/feign/2")
		public AssassinResult testFeign2() {
			return new AssassinResult(testService.test2().getData());
		}

	}
}
